package androidapp.firstapp;

import java.util.ArrayList;
import java.util.Random;
import java.util.Vector;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class Nine_puzzles extends Activity {

	ArrayList<Bitmap> chunkedImages;
	int blanknr;
	Button blankButton;
	Vector<Button> buttonVector;
	int size = 3;
	int[] game_array;
	int moveCount;
	BitmapDrawable removedFragment;
	int removedId;
	boolean isRunning;
	Button button0;
	Button button1;
	Button button2;
	Button button3;
	Button button4;
	Button button5;
	Button button6;
	Button button7;
	Button button8;


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_nine_puzzles);
		Intent intent = getIntent();
		String imgFile = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
		game_array = new int[size*size];
		moveCount = 0;
		int chunkNumbers = intent.getIntExtra("Chunks",size*size);
		splitImage(imgFile, chunkNumbers);
		 this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
			
		button0 = (Button) this.findViewById(R.id.button0);
		//button0.setBackground(new BitmapDrawable(chunkedImages.get(0)));
	
		button1 = (Button) this.findViewById(R.id.button1);
		//button1.setBackground(new BitmapDrawable(chunkedImages.get(1)));
		
		button2 = (Button) this.findViewById(R.id.button2);
		//button2.setBackground(new BitmapDrawable(chunkedImages.get(2)));
		
		button3 = (Button) this.findViewById(R.id.button3);
//		button3.setBackground(new BitmapDrawable(chunkedImages.get(3)));
		
		button4 = (Button) this.findViewById(R.id.button4);
	//	button4.setBackground(new BitmapDrawable(chunkedImages.get(4)));
		
		button5 = (Button) this.findViewById(R.id.button5);
		///button5.setBackground(new BitmapDrawable(chunkedImages.get(5)));
		
		button6 = (Button) this.findViewById(R.id.button6);
//		button6.setBackground(new BitmapDrawable(chunkedImages.get(6)));
		
		button7 = (Button) this.findViewById(R.id.button7);
//		button7.setBackground(new BitmapDrawable(chunkedImages.get(7)));
		
		button8 = (Button) this.findViewById(R.id.button8);
		//button8.setBackground(new BitmapDrawable(chunkedImages.get(8)));
		//button8.setBackground((new BitmapDrawable()));	
		
//		button8.setBackground(new BitmapDrawable(chunkedImages.get(8)));
		
		//chunkedImages.set(8, new BitmapDrawable().getBitmap());
		//blankButton  = button8;
		
		buttonVector = new Vector<Button>();
		buttonVector.add(button0);
		buttonVector.add(button1);
		buttonVector.add(button2);
		buttonVector.add(button3);
		buttonVector.add(button4);
		buttonVector.add(button5);
		buttonVector.add(button6);
		buttonVector.add(button7);
		buttonVector.add(button8);
		
		
		/*setButton(button0, 0);
		setButton(button1, 1);
		setButton(button2, 2);
		setButton(button3, 3);
		setButton(button4, 4);
		setButton(button5, 5);
		setButton(button6, 6);
		setButton(button7, 7);
		setButton(button8, 8);*/
		showPreview();
		
	}
	
	public boolean checkPossibility(int clickedIndex, int blankIndex){
		if (clickedIndex-blankIndex == size || 
				blankIndex-clickedIndex == size){
			return true;
		}
		if((clickedIndex-blankIndex == 1 || blankIndex-clickedIndex == 1))
			if ((clickedIndex % size == 0 && blankIndex % size ==(size-1)) || (blankIndex % size == 0 && clickedIndex % size ==(size-1))) return false;
			else return true;
	
	return false;
}
	
	
	public void shuffle(int[] array,int blankIndex) {
        Random random = new Random();
        int count = array.length-1;
        int lastmoved;
        for (int i = 0; i <size*size*size*size;){
        	lastmoved = random.nextInt(count);
        	if(checkPossibility(lastmoved, blankIndex)){
        		swap(array,lastmoved, blankIndex);
        		blankIndex = lastmoved;
        		i++;
        	}
        }
        
        
    }

    public static void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    
    @SuppressWarnings("deprecation")
	public void showPreview(){
    	for (int i = 0; i < size*size; i++){
    		game_array[i] = i;
    		}
    		Random random = new Random();
    		int blankIndex = random.nextInt(size*size-1);
            blankButton = buttonVector.get(blankIndex);
            removedId = blankIndex;
    		removedFragment = new BitmapDrawable(chunkedImages.get(removedId));
    		Log.d("PK", "blank: " + removedId);
    		chunkedImages.set(removedId, new BitmapDrawable().getBitmap());
    		//setButton(removedId,game_array[removedId]);
    		
    		for(int i=0; i<size*size; i++){
    					setButton(i,game_array[i]);
    		}
    		
    		
    		isRunning = false;
    		Toast.makeText(getApplicationContext(), "Click to mix", Toast.LENGTH_LONG).show();
    }
    
    public void runGame(View view){
    	if (!isRunning) {prepareGame();
    	isRunning = true;
    	}
    	else isRunning = true;
    }
    
	public void prepareGame(){
	shuffle(game_array, removedId);
		
		
		for(int i=0; i<size*size; i++){
			if (game_array[i] == removedId) blankButton = buttonVector.get(i);
			setButton(i,game_array[i]);
		}
		
		
	}
	
	@SuppressWarnings("deprecation")
	public void setButton(int buttonId, int imgNr){
		buttonVector.get(buttonId).setBackground(new BitmapDrawable(chunkedImages.get(imgNr)));
	}
	
	@SuppressWarnings("deprecation")
	public void setButton(Button button, int nr){
		if (nr>-1) {
	button.setBackground(new BitmapDrawable(chunkedImages.get(nr)));
	game_array[buttonVector.indexOf(button)] = nr;}
	    else button.setBackground((new BitmapDrawable()));	
	}
	

	
	
	
	public boolean checkNeightbour(Button buttonClicked, Button blankButton, Vector<Button> buttonVector, int size){
		int clickedIndex = buttonVector.indexOf(buttonClicked);
		int blankIndex = buttonVector.indexOf(blankButton);			
			if (clickedIndex-blankIndex == size || 
					blankIndex-clickedIndex == size){
				return true;
			}
			if((clickedIndex-blankIndex == 1 || blankIndex-clickedIndex == 1))
				if ((clickedIndex % size == 0 && blankIndex % size ==(size-1)) || (blankIndex % size == 0 && clickedIndex % size ==(size-1))) return false;
				else return true;
			return false;
	}
	
	public boolean checkWin (int[] game_array, int size){
		for (int i = 0;  i < (size*size); i++){
			if(game_array[i] == i) {
			//	Log.d("PK", "i: "+ i + "val: " + game_array[i]);
				//return false;
			  }
			else {
			//	Log.d("PK", "false");
				return false;
			}
		}
		//Log.d("PK", "true");
		return true;
	}
	
	public boolean switch_puzzles(int[] game_array, Button buttonClicked, Button blankButton, Vector<Button> buttonVector){
		int clickedIndex = buttonVector.indexOf(buttonClicked);
		int blankIndex = buttonVector.indexOf(blankButton);	
		int tmp = game_array[blankIndex];
	//	Log.d("PK", "BFblank: " + blankIndex +";" + game_array[blankIndex] +  " click: " + clickedIndex + ";" + game_array[clickedIndex]);
		game_array[blankIndex] = game_array[clickedIndex];
		game_array[clickedIndex] = tmp;
	//	Log.d("PK", "AFblank: " + blankIndex +";" + game_array[blankIndex] +  " click: " + clickedIndex + ";" + game_array[clickedIndex]);
		return true;
	}
	
	 @SuppressWarnings("deprecation")
	public void buttonClicked(View view) {
	 if (!isRunning) {prepareGame();
	    	isRunning = true;
	    	}
	    	else isRunning = true;
	 if(checkWin(game_array, size)) return;
	 if(checkNeightbour(((Button) view), blankButton, buttonVector, size )) {
	 switch_puzzles(game_array,((Button) view), blankButton, buttonVector);
	 blankButton.setBackground(view.getBackground());
	 view.setBackground(new BitmapDrawable());
	 blankButton = (Button) view;
	 moveCount++;
	 if(checkWin(game_array, size)){
		 Toast.makeText(getApplicationContext(), "WIN in " + moveCount + " moves.", Toast.LENGTH_LONG).show();
	 
	 blankButton.setBackground(removedFragment);
	 }
	 }
	 else 
		 return;
	 
		 
	//button4.setBackground(view.getBackground());
	//((Button) view).setBackground((new BitmapDrawable()));	
	 }
	 

	public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

         int newfHeight = height;
         int newfWidth = width;

        while ((newfHeight / inSampleSize) > reqHeight
                || (newfWidth / inSampleSize) > reqWidth) {
            inSampleSize = inSampleSize * 2;
            
        }
        options.inSampleSize = inSampleSize;
    }
        return inSampleSize;
}
	
public void splitImage(String imgPath, int chunkNumbers) {	
		
		//For the number of rows and columns of the grid to be displayed
		int rows,cols;
		
		//For height and width of the small image chunks 
		int chunkHeight,chunkWidth;
		
		//To store all the small image chunks in bitmap format in this list 
		chunkedImages = new ArrayList<Bitmap>(chunkNumbers);
		
		//Getting the scaled bitmap of the source image
		
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imgPath, options);
     
        options.inSampleSize= calculateInSampleSize(options, 1000,1800);
        options.inJustDecodeBounds = false;
		Bitmap myBitmap = BitmapFactory.decodeFile(imgPath,options);
		BitmapDrawable drawable = new BitmapDrawable(getResources(), myBitmap);
		Bitmap bitmap = drawable.getBitmap();
		

		//Toast.makeText(Nine_puzzles.this, Integer.toString(bitmap.getWidth()), Toast.LENGTH_SHORT).show();
		
		Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), true);
		
		rows = cols = (int) Math.sqrt(chunkNumbers);
		chunkHeight = bitmap.getHeight()/rows;
		chunkWidth = bitmap.getWidth()/cols;
		
		//xCoord and yCoord are the pixel positions of the image chunks
		int yCoord = 0;
		for(int x=0; x<rows; x++){
			int xCoord = 0;
			for(int y=0; y<cols; y++){
				chunkedImages.add(Bitmap.createBitmap(scaledBitmap, xCoord, yCoord, chunkWidth, chunkHeight));
				xCoord += chunkWidth;
			}
			yCoord += chunkHeight;
		}
		
	}


	/*
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.nine_puzzles, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}*/

}
